// main.go
package main

import (
	"fmt"
	"gitee.com/chenwl888/gotools/utils/pprof"
	"github.com/lxn/walk"
	"github.com/lxn/walk/declarative"
	"github.com/shirou/gopsutil/process"
	"log"
	"os"
	"sort"
	"time"
)

type ProcessInfo struct {
	Name     string
	MemUsage float32 // 内存使用率
	Mem      uint64  // 使用的内存
}

type ProcessCPUInfo struct {
	Name string  // 进程名称
	CPU  float64 // CPU使用率
}

// ServerModel 用于在TableView中显示进程信息
type ServerModel struct {
	walk.TableModelBase
	items []ProcessInfo
}

// ClientModel 用于在TableView中显示CPU进程信息
type ClientModel struct {
	walk.TableModelBase
	items []ProcessCPUInfo
}

func (m *ServerModel) RowCount() int {
	return len(m.items)
}

func (m *ServerModel) Value(row, col int) interface{} {
	item := m.items[row]
	switch col {
	case 0:
		return item.Name
	case 1:
		return item.MemUsage
	case 2:
		return float64(item.Mem) / 1024 / 1024 // 转换为MB
	}
	panic("unexpected col")
}

func (m *ServerModel) setItems(items []ProcessInfo) {
	m.items = items
	m.PublishRowsReset() // 通知视图数据已重置，需要刷新
}

func (m *ClientModel) RowCount() int {
	return len(m.items)
}

func (m *ClientModel) Value(row, col int) interface{} {
	item := m.items[row]
	switch col {
	case 0:
		return item.Name
	case 1:
		return item.CPU
	}
	panic("unexpected col")
}

func (m *ClientModel) setCpuItems(items []ProcessCPUInfo) {
	m.items = items
	m.PublishRowsReset() // 通知视图数据已重置，需要刷新
}

var mw *walk.MainWindow
var serverModel *ServerModel
var clientModel *ClientModel

func getProcessList() {
	for {
		processes, err := process.Processes()
		if err != nil {
			fmt.Printf("获取进程信息失败: %v\n", err)
			os.Exit(1)
		}

		var procs []ProcessInfo
		for _, p := range processes {
			name, err := p.Name()
			if err != nil {
				continue
			}

			memInfo, err := p.MemoryInfo()
			if err != nil {
				continue
			}

			memPercent, err := p.MemoryPercent()
			if err != nil {
				continue
			}

			procs = append(procs, ProcessInfo{
				Name:     name,
				MemUsage: memPercent,
				Mem:      memInfo.RSS,
			})
		}
		// 排序，根据内存使用量从高到低
		sort.Slice(procs, func(i, j int) bool {
			return procs[i].Mem > procs[j].Mem
		})

		// 只保留前五条
		if len(procs) > 5 {
			procs = procs[:10]
		}

		//在UI线程中更新表格
		mw.Synchronize(func() {
			serverModel.setItems(procs)
		})

		// 等待一段时间后再次更新
		time.Sleep(18)
	}
}

func getProcessCpuList() {
	for {
		processes, err := process.Processes()
		if err != nil {
			fmt.Printf("获取进程列表时出错: %v\n", err)
			os.Exit(1)
		}

		var procCPUInfo []ProcessCPUInfo
		for _, p := range processes {
			name, err := p.Name()
			if err != nil {
				continue
			}
			cpu, err := p.CPUPercent()
			if err != nil {
				continue
			}

			procCPUInfo = append(procCPUInfo, ProcessCPUInfo{
				Name: name,
				CPU:  cpu,
			})
		}
		// 排序
		sort.Slice(procCPUInfo, func(i, j int) bool {
			return procCPUInfo[i].CPU > procCPUInfo[j].CPU
		})

		// 只保留前五条
		if len(procCPUInfo) > 5 {
			procCPUInfo = procCPUInfo[:10]
		}

		// 在UI线程中更新表格
		mw.Synchronize(func() {
			clientModel.setCpuItems(procCPUInfo)
		})

		// 等待一段时间后再次更新
		time.Sleep(18)
	}
}

func start() {
	serverModel = new(ServerModel)
	clientModel = new(ClientModel)

	// 初始化GUI应用程序
	if err := (declarative.MainWindow{
		AssignTo: &mw,
		Title:    "WebSocket 消息测试工具",
		Layout:   declarative.VBox{},
		Size:     declarative.Size{Width: 800, Height: 800},
		Children: []declarative.Widget{
			&declarative.Composite{
				Layout: declarative.HBox{},
				Children: []declarative.Widget{
					&declarative.PushButton{
						Text:    "webSocket服务器",
						MaxSize: declarative.Size{Width: 120, Height: 40},
						//OnClicked: cb,
					},
				},
			},
			declarative.TableView{
				Columns: []declarative.TableViewColumn{
					{Title: "进程"},
					{Title: "内存使用率(%)"},
					{Title: "内存使用量(MB)"},
				},
				Model: serverModel,
			},
			&declarative.Composite{
				Layout: declarative.HBox{},
				Children: []declarative.Widget{
					&declarative.PushButton{
						Text:    "webClient客户端",
						MaxSize: declarative.Size{Width: 120, Height: 40},
						//OnClicked: cb,
					},
				},
			},
			declarative.TableView{
				Columns: []declarative.TableViewColumn{
					{Title: "进程"},
					{Title: "CPU使用率(%)"},
				},
				Model: clientModel,
			},
		},
	}).Create(); err != nil {
		log.Fatal(err)
		return
	}

	// 启动后台goroutine定期更新进程信息
	go getProcessList()
	go getProcessCpuList()

	mw.Run() // 启动事件处理循环
}

func main() {
	pprof.InitPprof()

	start() // 启动UI并在后台获取进程信息
}
